package cn.mujiankeji.mbrowser.数据.数据库

import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import androidx.room.Update
import cn.mujiankeji.mbrowser.工具.JSON
import cn.mujiankeji.mbrowser.数据.配置项.应用配置
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.Serializable
import java.io.File
import java.util.UUID

/**
 * 用户脚本数据模型
 * 
 * 用于存储和管理浏览器用户脚本（油猴脚本）
 * 支持脚本的启用/禁用、URL匹配、执行时机等功能
 */
@Entity(tableName = "UserScript")
@TypeConverters(UserScriptStringListConverter::class)
data class DBUserScript(
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0,
    
    /**
     * 脚本启用状态
     * true: 启用，false: 禁用
     */
    @ColumnInfo(name = "enable", defaultValue = "1")
    var 启用: Boolean = true,
    
    /**
     * 脚本名称
     */
    @ColumnInfo(name = "name", defaultValue = "")
    var 名称: String = "",
    
    /**
     * 脚本作用地址（匹配规则）
     * 每条规则一行，以换行符分隔
     */
    @ColumnInfo(name = "match", defaultValue = "")
    var 匹配地址: List<String> = emptyList(),
    
    /**
     * 脚本运行时机
     * 支持：document-start, document-end, document-idle, document-body
     * 可同时属于多个，以换行符分隔
     */
    @ColumnInfo(name = "runat", defaultValue = "document-end")
    var 运行时机: List<String> = listOf("document-end"),
    
    /**
     * 脚本需要使用的油猴API（GM_*函数）
     * 每条一行，以换行符分隔
     */
    @ColumnInfo(name = "gm_api", defaultValue = "")
    var 油猴API: List<String> = emptyList(),
    
    /**
     * 脚本允许连接的跨域URL
     * 每条一行，以换行符分隔
     */
    @ColumnInfo(name = "connect", defaultValue = "")
    var 跨域连接: List<String> = emptyList(),
    
    /**
     * 脚本不良引导说明
     * 用于标注脚本可能存在的不良行为
     */
    @ColumnInfo(name = "antifeature", defaultValue = "")
    var 不良引导说明: String = "",
    
    /**
     * 脚本标识符（用于文件保存）
     * 如为空，将自动生成
     */
    @ColumnInfo(name = "sign", defaultValue = "")
    var 标识符: String = "",
    
    /**
     * 脚本依赖资源
     * 格式：URL或路径，每行一条
     */
    @ColumnInfo(name = "require", defaultValue = "")
    var 依赖资源: List<String> = emptyList(),
    
    /**
     * 脚本预加载资源
     * 格式：key=url，每行一条
     */
    @ColumnInfo(name = "resource", defaultValue = "")
    var 预加载资源: List<String> = emptyList(),
    
    /**
     * 脚本版本
     */
    @ColumnInfo(name = "version", defaultValue = "")
    var 版本: String = "",
    
    /**
     * 脚本作者
     */
    @ColumnInfo(name = "author", defaultValue = "")
    var 作者: String = "",
    
    /**
     * 脚本描述
     */
    @ColumnInfo(name = "description", defaultValue = "")
    var 描述: String = "",
    
    /**
     * 脚本更新地址
     */
    @ColumnInfo(name = "update_url", defaultValue = "")
    var 更新地址: String = "",
    
    /**
     * 脚本更新时间
     * 使用Long表示秒级时间戳
     */
    @ColumnInfo(name = "update_time")
    var 更新时间: Long = System.currentTimeMillis() / 1000
) {
    /**
     * 获取脚本文件路径
     * 如果标识符为空，将自动生成一个唯一标识符
     *
     * @return 脚本文件的完整路径
     */
    fun 获取文件路径(): String {
        if (标识符.isEmpty()) {
            标识符 = UUID.randomUUID().toString()
        }
        return 应用配置.路径_用户脚本 + 标识符 + ".js"
    }
}

/**
 * 用于Room数据库的字符串列表转换器
 */
class UserScriptStringListConverter {
    @TypeConverter
    fun fromStringList(value: List<String>?): String? {
        return value?.joinToString("\n")
    }
    
    @TypeConverter
    fun toStringList(value: String?): List<String>? {
        return value?.split("\n")?.filter { it.isNotEmpty() } ?: emptyList()
    }
}

/**
 * 用户脚本数据访问对象
 * 提供用户脚本的数据库操作接口
 */
@Dao
interface DaoUserScript {
    /**
     * 获取所有用户脚本
     * @return Flow包装的脚本列表
     */
    @Query("SELECT * FROM UserScript ORDER BY id ASC")
    fun 获取所有用户脚本(): Flow<List<DBUserScript>>
    
    /**
     * 获取所有启用的用户脚本
     * @return Flow包装的已启用脚本列表
     */
    @Query("SELECT * FROM UserScript WHERE enable = 1 ORDER BY id ASC")
    fun 获取已启用用户脚本(): Flow<List<DBUserScript>>
    
    /**
     * 根据ID获取特定脚本
     * @param id 脚本ID
     * @return Flow包装的脚本（可能为null）
     */
    @Query("SELECT * FROM UserScript WHERE id = :id")
    fun 根据ID获取用户脚本(id: Long): Flow<DBUserScript?>
    
    /**
     * 根据ID获取特定脚本（挂起函数版本）
     * @param id 脚本ID
     * @return 脚本对象（可能为null）
     */
    @Query("SELECT * FROM UserScript WHERE id = :id")
    suspend fun 获取用户脚本(id: Long): DBUserScript?
    
    /**
     * 根据名称查找脚本
     * @param 名称 脚本名称
     * @return Flow包装的脚本列表
     */
    @Query("SELECT * FROM UserScript WHERE name LIKE '%' || :名称 || '%'")
    fun 根据名称查找用户脚本(名称: String): Flow<List<DBUserScript>>
    
    /**
     * 插入用户脚本
     * @param 用户脚本 要插入的脚本对象
     * @return 插入后的脚本ID
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun 插入用户脚本(用户脚本: DBUserScript): Long
    
    /**
     * 更新用户脚本
     * @param 用户脚本 要更新的脚本对象
     */
    @Update
    suspend fun 更新用户脚本(用户脚本: DBUserScript)
    
    /**
     * 删除用户脚本
     * @param 用户脚本 要删除的脚本对象
     */
    @Delete
    suspend fun 删除用户脚本(用户脚本: DBUserScript)
    
    /**
     * 清空所有用户脚本
     */
    @Query("DELETE FROM UserScript")
    suspend fun 删除所有用户脚本()
    
    /**
     * 更新脚本启用状态
     * @param id 脚本ID
     * @param 启用 是否启用
     */
    @Query("UPDATE UserScript SET enable = :启用 WHERE id = :id")
    suspend fun 更新用户脚本状态(id: Long, 启用: Boolean)

    /**
     * 根据URL获取匹配的脚本
     * 注意：这个查询可能不高效，因为需要在应用层进行URL匹配
     */
    @Query("SELECT * FROM UserScript WHERE enable = 1")
    suspend fun 获取可能匹配URL的脚本(): List<DBUserScript>

    /**
     * 根据标识符查找脚本
     */
    @Query("SELECT * FROM UserScript WHERE sign = :标识符 LIMIT 1")
    suspend fun 根据标识符获取脚本(标识符: String): DBUserScript?

    /**
     * 查找具有特定运行时机的脚本
     */
    @Query("SELECT * FROM UserScript WHERE enable = 1")
    suspend fun 获取所有启用脚本(): List<DBUserScript>
}


